<template>
  <transition name="fade">
    <div class="draggable-popup" v-if="visible">
      <div class="draggable-popup-title" v-on:mousedown="startDrag">
        <span>{{ title }}</span>
        <i class="draggable-popup-closer el-icon-close" v-on:click="closePopup"></i>
      </div>
      <div class="draggable-popup-content">
        <slot></slot>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  name: "draggable-popup",
  props: {
    target: String,
    title: String
  },
  data() {
    return {
      visible: true,
      targetElment: null,
      isDragging: false,
      downX: -1,
      downY: -1,
      offsetTop: 0,
      offsetLeft: 0
    };
  },
  mounted() {
    const _this = this;
    _this.initPopup();
  },
  methods: {
    initPopup() {
      const _this = this;
      _this.targetElment = document.getElementById(_this.target);
      _this.targetElment.appendChild(_this.$el);
    },
    startDrag(e) {
      const _this = this;
      _this.isDragging = true;
      _this.downX = e.clientX;
      _this.downY = e.clientY;
      _this.offsetTop = _this.$el.offsetTop;
      _this.offsetLeft = _this.$el.offsetLeft;
      _this.$el.style.top = _this.offsetTop + "px";
      _this.$el.style.left = _this.offsetLeft + "px";
      _this.$el.style.bottom = "unset";
      _this.$el.style.right = "unset";
      _this.targetElment.addEventListener("mousemove", _this.dragging);
      _this.targetElment.addEventListener("mouseup", _this.stopDrag);
    },
    dragging(e) {
      const _this = this;
      if (_this.isDragging) {
        let moveX = e.clientX - _this.downX;
        let moveY = e.clientY - _this.downY;
        let targetWidth = _this.targetElment.offsetWidth;
        let targetHeight = _this.targetElment.offsetHeight;
        let curWidth = _this.$el.offsetWidth;
        let curHeight = _this.$el.offsetHeight;
        let maxTop = targetHeight - curHeight;
        let maxLeft = targetWidth - curWidth;
        let top = _this.offsetTop + moveY;
        if (top < 0) {
          top = 0;
        } else if (top > maxTop) {
          top = maxTop;
        }
        let left = _this.offsetLeft + moveX;
        if (left < 0) {
          left = 0;
        } else if (left > maxLeft) {
          left = maxLeft;
        }
        _this.$el.style.top = top + "px";
        _this.$el.style.left = left + "px";
      }
    },
    stopDrag() {
      const _this = this;
      _this.isDragging = false;
      _this.targetElment.removeEventListener("mousemove", _this.dragging);
      _this.targetElment.removeEventListener("mouseup", _this.stopDrag);
    },
    closePopup() {
      const _this = this;
      _this.visible = false;
      _this.$emit("close");
    }
  }
};
</script>

<style>
.draggable-popup {
  padding: 5px;
  background-color: rgba(255, 255, 255, 0.6);
  border-radius: 5px;
  border: 1px solid lightgray;
  box-shadow: 3px 3px 2px 1px rgba(0, 0, 0, 0.3);
  font-size: 14px;
}

.draggable-popup-title {
  background-color: #79c74e;
  color: white;
  height: 24px;
  line-height: 24px;
  text-align: left;
  padding-left: 5px;
  padding-right: 30px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  position: relative;
  cursor: move;
  user-select: none;
}

.draggable-popup-closer {
  position: absolute;
  right: 5px;
  top: 5px;
  cursor: pointer;
}
</style>


